#include "PersonParser.h"

#include "QStringParser.h"

#include <QXmlStreamReader>
#include <QString>

namespace Ipc2581b
{

PersonParser::PersonParser(
    QStringParser *&_nameParser
    , QStringParser *&_enterpriseRefParser
    , QStringParser *&_titleParser
    , QStringParser *&_emailParser
    , QStringParser *&_phoneParser
    , QStringParser *&_faxParser
    , QStringParser *&_mailStopParser
    , QStringParser *&_publicKeyParser
):    m_nameParser(_nameParser)
    , m_enterpriseRefParser(_enterpriseRefParser)
    , m_titleParser(_titleParser)
    , m_emailParser(_emailParser)
    , m_phoneParser(_phoneParser)
    , m_faxParser(_faxParser)
    , m_mailStopParser(_mailStopParser)
    , m_publicKeyParser(_publicKeyParser)
{

}

bool PersonParser::parse(QXmlStreamReader *reader)
{
    /* Pre */

    m_result.reset(new Person());

    /* Attributes */

    QStringRef data;
    if (reader->attributes().hasAttribute(QStringLiteral("name")))
    {
        data = reader->attributes().value(QStringLiteral("name"));
        if (!m_nameParser->parse(reader, data))
            return false;
        m_result->name = m_nameParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("name: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("enterpriseRef")))
    {
        data = reader->attributes().value(QStringLiteral("enterpriseRef"));
        if (!m_enterpriseRefParser->parse(reader, data))
            return false;
        m_result->enterpriseRef = m_enterpriseRefParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("enterpriseRef: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("title")))
    {
        data = reader->attributes().value(QStringLiteral("title"));
        if (!m_titleParser->parse(reader, data))
            return false;
        m_result->titleOptional = Optional<QString>(m_titleParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("email")))
    {
        data = reader->attributes().value(QStringLiteral("email"));
        if (!m_emailParser->parse(reader, data))
            return false;
        m_result->emailOptional = Optional<QString>(m_emailParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("phone")))
    {
        data = reader->attributes().value(QStringLiteral("phone"));
        if (!m_phoneParser->parse(reader, data))
            return false;
        m_result->phoneOptional = Optional<QString>(m_phoneParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("fax")))
    {
        data = reader->attributes().value(QStringLiteral("fax"));
        if (!m_faxParser->parse(reader, data))
            return false;
        m_result->faxOptional = Optional<QString>(m_faxParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("mailStop")))
    {
        data = reader->attributes().value(QStringLiteral("mailStop"));
        if (!m_mailStopParser->parse(reader, data))
            return false;
        m_result->mailStopOptional = Optional<QString>(m_mailStopParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("publicKey")))
    {
        data = reader->attributes().value(QStringLiteral("publicKey"));
        if (!m_publicKeyParser->parse(reader, data))
            return false;
        m_result->publicKeyOptional = Optional<QString>(m_publicKeyParser->result());
    }

    /* Elements */

    while (reader->readNextStartElement())
    {
        auto name = reader->name();
            reader->skipCurrentElement();
    }

    /* Post */

    // TODO: Check multiplicity of elements/attributes

    return true;
}

Person *PersonParser::result()
{
    return m_result.take();
}

}